/*
 * Copyright (c) 2023-2025 110476592@qq.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @file painter_factory.h
 * @brief 截图工具 
 * @author 110476592@qq.com 
 * @note   承接Qt项目外包定制开发。长期接收C++项目实训学徒,联系QQ：110476592。
 */

 
#ifndef ACTION_FACTORY_H
#define ACTION_FACTORY_H
#include <painter/abs_painter.h>
#include <QObject>
#include <QMutex>

// 前向声明 AbsPainter 类，告知编译器该类的存在，避免头文件循环包含


/**
 * @class PainterFactory
 * @brief 命令工厂类，用于创建不同类型的 AbsPainter 对象，采用单例模式实现
 * 
 * 该类提供了创建 AbsPainter 对象的统一接口，确保在整个应用程序中只有一个工厂实例。
 */
class PainterFactory : public QObject {
  // 声明该类使用 Qt 的信号与槽机制
  Q_OBJECT
public:
  /**
   * @brief 获取 PainterFactory 对象，单例模式
   * 
   * 该方法保证在整个应用程序生命周期中只有一个 PainterFactory 实例，
   * 并通过互斥锁确保线程安全。
   * 
   * @return 返回 PainterFactory 单例对象的引用
   */
  static PainterFactory &getInstance();

public:
  /**
  * @brief 根据绘图类型获取对应的绘图器对象
  * 
  * 该方法通过传入的绘图类型，从内部维护的绘图器映射中查找并返回对应的绘图器对象。
  * 如果找不到对应的绘图器，可能会导致未定义行为，调用者需要确保传入的类型已被注册。
  * 
  * @param t 要获取的绘图器的类型
  * @return 返回对应绘图类型的 AbsPainter 对象的引用
  */
  AbsPainter& getPainter(PainterType t);

  /**
  * @brief 注册一个绘图器到工厂中
  * 
  * 该方法将指定类型的绘图器注册到工厂内部的绘图器映射中，以便后续通过 `getPainter` 方法获取。
  * 如果该类型已经注册过，原有的绘图器对象将被新传入的对象替换。
  * 
  * @param t 要注册的绘图器的类型
  * @param painter 要注册的绘图器对象指针，工厂将接管该对象的所有权
  */
  void  registerPainter(PainterType t,AbsPainter *painter);


private:
  /**
   * @brief 构造函数
   * 
   * 初始化 PainterFactory 对象，由于采用单例模式，该构造函数为私有。
   * 
   * @param parent 父对象指针，默认为 nullptr，用于 Qt 的对象树管理
   */
  explicit PainterFactory(QObject *parent = nullptr);

  /**
   * @brief 拷贝构造函数 = delete
   * 
   * 禁止使用拷贝构造函数创建 PainterFactory 对象，保证单例模式的唯一性。
   * 
   * @warning 禁止使用拷贝构造函数创建 PainterFactory 对象
   */
  PainterFactory(const PainterFactory &) = delete;

  /**
   * @brief =运算符重载 = delete
   * 
   * 禁止使用赋值的方式创建 PainterFactory 对象，保证单例模式的唯一性。
   * 
   * @warning 禁止使用赋值的方式创建 PainterFactory 对象
   */
  PainterFactory &operator=(const PainterFactory &) = delete;

private:
  // 单例 PainterFactory 对象指针，用于保存全局唯一的工厂实例
  static PainterFactory *s_instance; 
  // 互斥锁，用于保证在多线程环境下获取单例对象的线程安全
  static QMutex s_mutex;

  QMap<PainterType , AbsPainter*> m_painters; ///< 绘图工具
};


#endif
